/*
 * Copyright (c) 2014. Lorem ipsum dolor sit amet, consectetur adipiscing elit.
 * http://www.apache.org/licenses/LICENSE-2.0
 */

package net.MinaEngine.core;

import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.session.IoSession;
import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
import org.apache.mina.filter.codec.ProtocolDecoderOutput;

/**
 * @author :石头哥哥<br/>
 *         Project:FrameServer1.0
 *         Date: 13-5-19
 *         Time: 下午4:27
 * A {@link org.apache.mina.filter.codec.ProtocolDecoder} that cumulates the content of received
 * buffers to a <em>cumulative buffer</em> to help users implement decoders.
 *  it's easiest to wait until all data is available
 *
 *  相应的
 */
public class MServerProtocolDecoder extends CumulativeProtocolDecoder {


//    private final ClassLoader classLoader;

    private int maxObjectSize = 1048576; // 1MB


     public MServerProtocolDecoder(){
//         this(Thread.currentThread().getContextClassLoader());
     }

//
//    /**
//     * Creates a new instance with the specified {@link ClassLoader}.
//     */
//    public MServerProtocolDecoder(ClassLoader classLoader) {
//        if (classLoader == null) {
//            throw new IllegalArgumentException("classLoader");
//        }
//        this.classLoader = classLoader;
//    }


    /**
     * Returns the allowed maximum size of the object to be decoded.
     * If the size of the object to be decoded exceeds this value, this
     * decoder will throw a {@link org.apache.mina.core.buffer.BufferDataException}.  The default
     * value is <tt>1048576</tt> (1MB).
     */
    public int getMaxObjectSize() {
        return maxObjectSize;
    }

    /**
     * Sets the allowed maximum size of the object to be decoded.
     * If the size of the object to be decoded exceeds this value, this
     * decoder will throw a {@link org.apache.mina.core.buffer.BufferDataException}.  The default
     * value is <tt>1048576</tt> (1MB).
     */
    public void setMaxObjectSize(int maxObjectSize) {
        if (maxObjectSize <= 0) {
            throw new IllegalArgumentException("maxObjectSize: " + maxObjectSize);
        }

        this.maxObjectSize = maxObjectSize;
    }


    /**
     * decode package :
     *        lengthFieldLength:1，2 ，4(byte)
     *
     * Implement this method to consume the specified cumulative buffer and
     * decode its content into message(s).
     *
     * @param in the cumulative buffer
     * @return <tt>true</tt> if and only if there's more to decode in the buffer
     *         and you want to have <tt>doDecode</tt> method invoked again.
     *         Return <tt>false</tt> if remaining data is not enough to decode,
     *         then this method will be invoked again when more data is cumulated.
     * @throws Exception if cannot decode <tt>in</tt>.
     *
     * 数据包解析
     */
    @Override
    protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
        //not enough  data will be return false
        if (!(in.prefixedDataAvailable(2,maxObjectSize))){
            return false;
        }
        //now let's decode message to the  IoBuffer;
        // mark <= position <= limit <= capacity
        // if remaining data is not enough to decode （value:MServerConfig.lengthFieldLength=2）;
//        if (in.remaining()< MServerConfig.lengthFieldLength){
//            return false;
//        }
        int packLength=in.getUnsignedShort();//get pack length ,increments the position by two
        //the dataLength is not enough to decode
        if (in.remaining()<packLength){
            return false;
        }
        byte[]packMessage=new byte[packLength];
        in.get(packMessage);
        //warp byte array to IoBuffer ,add to the messageQueue
        out.write(IoBuffer.wrap(packMessage));
        out.flush(session.getFilterChain().getNextFilter("protocolCodecFilter"),session);//Flushes all messages to the NextFilter---->executors logic
        return true;  //decode ok
    }
}
